package club.xiaojiawei.array;

/**
 * @author 肖嘉威
 * @version 1.0
 * @date 6/24/22 4:32 PM
 * @question 463. 岛屿的周长
 * @description 给定一个 row x col 的二维网格地图 grid ，其中：grid[i][j] = 1 表示陆地， grid[i][j] = 0 表示水域。
 * 网格中的格子 水平和垂直 方向相连（对角线方向不相连）。整个网格被水完全包围，但其中恰好有一个岛屿（或者说，一个或多个表示陆地的格子相连组成的岛屿）。
 * 岛屿中没有“湖”（“湖” 指水域在岛屿内部且不和岛屿周围的水相连）。格子是边长为 1 的正方形。网格为长方形，且宽度和高度均不超过 100 。计算这个岛屿的周长。
 */
public class IslandPerimeter463 {

    public static void main(String[] args) {
        IslandPerimeter463 test = new IslandPerimeter463();
        int result = test.islandPerimeter(new int[][]{{1,1,1},{1,0,1}});
        System.out.println(result);
    }

    /**
     * 模拟
     * 时间复杂度：O(nm)
     * 空间复杂度：O(1)
     * @param grid
     * @return
     */
    public int islandPerimeter(int[][] grid) {
        int theMeasureOfArea = 0;
        for (int i = 0; i < grid.length; i++) {
            int[] row = grid[i];
            for (int j = 0; j < row.length; j++) {
                if (row[j] == 1){
                    if (j == 0 || row[j - 1] == 0){
                        theMeasureOfArea += 2;
                    }
                    if (i == 0 || grid[i - 1][j] == 0){
                        theMeasureOfArea += 2;
                    }
                }
            }
        }
        return theMeasureOfArea;
    }

    static int[] dx = {0, 1, 0, -1};
    static int[] dy = {1, 0, -1, 0};

    /**
     * 官方-迭代
     * 时间复杂度：O(nm)
     * 空间复杂度：O(1)
     * @param grid
     * @return
     */
    public int islandPerimeter2(int[][] grid) {
        int n = grid.length, m = grid[0].length;
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (grid[i][j] == 1) {
                    int cnt = 0;
                    for (int k = 0; k < 4; ++k) {
                        int tx = i + dx[k];
                        int ty = j + dy[k];
                        if (tx < 0 || tx >= n || ty < 0 || ty >= m || grid[tx][ty] == 0) {
                            cnt += 1;
                        }
                    }
                    ans += cnt;
                }
            }
        }
        return ans;
    }


    /**
     * 官方-dfs
     * 时间复杂度：O(nm)
     * 空间复杂度：O(nm)
     * @param grid
     * @return
     */
    public int islandPerimeter3(int[][] grid) {
        int n = grid.length, m = grid[0].length;
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (grid[i][j] == 1) {
                    ans += dfs(i, j, grid, n, m);
                }
            }
        }
        return ans;
    }

    public int dfs(int x, int y, int[][] grid, int n, int m) {
        if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 0) {
            return 1;
        }
        if (grid[x][y] == 2) {
            return 0;
        }
        grid[x][y] = 2;
        int res = 0;
        for (int i = 0; i < 4; ++i) {
            int tx = x + dx[i];
            int ty = y + dy[i];
            res += dfs(tx, ty, grid, n, m);
        }
        return res;
    }
}
